#! /usr/bin/env python

import sys
#head format
# 8 ascii : version of this data format (0)
# 80 ascii : local patient identification
# 80 ascii : local recording identification
# 8 ascii : startdate of recording (dd.mm.yy)
# 8 ascii : starttime of recording (hh.mm.ss)
# 8 ascii : number of bytes in header record
# 44 ascii : reserved
# 8 ascii : number of data records (-1 if unknown)
# 8 ascii : duration of a data record, in seconds
# 4 ascii : number of signals (ns) in data record
# ns * 16 ascii : ns * label (e.g. EEG FpzCz or Body temp)
# ns * 80 ascii : ns * transducer type (e.g. AgAgCl electrode)
# ns * 8 ascii : ns * physical dimension (e.g. uV or degreeC)
# ns * 8 ascii : ns * physical minimum (e.g. -500 or 34)
# ns * 8 ascii : ns * physical maximum (e.g. 500 or 40)
# ns * 8 ascii : ns * digital minimum (e.g. -2048)
# ns * 8 ascii : ns * digital maximum (e.g. 2047)
# ns * 80 ascii : ns * prefiltering (e.g. HP:0.1Hz LP:75Hz)
# ns * 8 ascii : ns * nr of samples in each data record
# ns * 32 ascii : ns * reserved

# DATA RECORD
# one record after record
# nr of samples[1] * integer : first signal in the data record
# nr of samples[2] * integer : second signal
# ..
# ..
# nr of samples[ns] * integer : last signal


head = {}
record = {}
ns = 0
nr = 0
labels = []
samples = []
scalfc = []
dc = []
keylist = ['version', 
            'petientID', 'recordID', 
            'startDate', 'startTime', 
            'headLenthByte', 'reserved', 
            'NumOfRecords', 'secondsPerRecord', 'NumOfSignals',
            'labels', 'transducerType', 
            'physicalDimension', 'physicalMinimum', 'physicalMaximum',
            'digitalMinimum', 'digitalMaximum',
            'preFiltering',
            'samples', 
            'tailReserved' ]


def readedf(filename, signalName = '', records = 0):
    """
    @filename 'test.edf'
    @head dict
    @record dict      
    """
    global ns
    global nr
    f = open(filename,'r')
    head['version'] = f.read(8)
    head['petientID'] = f.read(80)
    head['recordID'] = f.read(80)
    head['startDate'] = f.read(8)
    head['startTime'] = f.read(8)
    head['headLenthByte'] = int(f.read(8))
    head['reserved'] = f.read(44)
    head['NumOfRecords'] = int(f.read(8))

    nr = int(head['NumOfRecords']) 
    head['secondsPerRecord'] = f.read(8)
    head['NumOfSignals'] = f.read(4)
    ns = int(head['NumOfSignals']) 

    head['labels'] = f.read(16 * ns)
    strlabels = head['labels']
    labels = [strlabels[x:x+16] for x in range(0,len(strlabels),16)]

    head['labels'] = labels

    head['transducerType'] = f.read(80 * ns)
    head['physicalDimension'] = f.read(8 * ns)
    physicalDimension = head['physicalDimension']
    head['physicalDimension'] = [physicalDimension[x:x+8] for x in range(0, len(physicalDimension),8)]

    head['physicalMinimum'] = f.read(8 * ns)
    physicalMinimum = [int(x) for x in head['physicalMinimum'].split()]
    head['physicalMinimum'] = physicalMinimum
    head['physicalMaximum'] = f.read(8 * ns)
    physicalMaximum = [int(x) for x in head['physicalMaximum'].split()]
    head['physicalMaximum'] = physicalMaximum
    head['digitalMinimum'] = f.read(8 * ns)
    digitalMinimum = [int(x) for x in head['digitalMinimum'].split()]
    head['digitalMinimum'] = digitalMinimum
    head['digitalMaximum'] = f.read(8 * ns)
    digitalMaximum = [int(x) for x in head['digitalMaximum'].split()]
    head['digitalMaximum'] = digitalMaximum

    for i in range(ns):
        scanfci = float(physicalMaximum[i] - physicalMinimum[i]) / float(digitalMaximum[i] - digitalMinimum[i])
        dci = physicalMaximum[i] - scanfci*digitalMaximum[i]
        scalfc.append(scanfci)
        dc.append(dci)

    head['preFiltering'] = f.read(80 * ns)
    head['samples'] = f.read(8 * ns)
    samples = [int(x) for x in head['samples'].split()]
    head['samples'] = samples
    head['tailReserved'] = f.read(32 * ns)
    f.close()

def str2signedint(str):
    if len(str) < 2:
        return None
    datal = ord(str[0])
    datah = ord(str[1])
    #negative data
    if datah > 127:
        return datah * 256 + datal - 65536
    else:
        return datah * 256 + datal
def getrecord(filename, name, startrecord = 0, numberrecord = 1):
    global ns
    global nr
    index = -1
    labels = head['labels']
    samples = head['samples']

    for item in labels:
        if item.find(name) >= 0:
            index = labels.index(item)
            break
    if index == -1:
         return None
    
    f = open(filename, 'r')
    
    seeki = head['headLenthByte']

    totalsamplesperrecord = 0
    for i in range(ns):
        totalsamplesperrecord += samples[i] * 2
    seeki += startrecord * totalsamplesperrecord
    for i in range(index):
        seeki += samples[i] * 2

    f.seek(seeki)
    datastr = f.read(samples[index] * numberrecord * 2)
    data = [str2signedint(datastr[x:x+2]) * scalfc[index] + dc[index] for x in range(0, len(datastr), 2)]   
    f.close()
    return data
    
def recultTreat(datas):
    for data in datas:
        print data

def main():
    args = sys.argv
    if len(args)< 1:
        sys.exit(1)
    if len(args) >= 2:
        readedf(args[1])
        # print head
    if len(args) == 3:
        data = getrecord(args[1], args[2])
        recultTreat(data)
    if len(args) == 4:
        data = getrecord(args[1], args[2], int(args[3]))
        recultTreat(data)
    if len(args) == 5:
        data = getrecord(args[1], args[2], int(args[3]), int(args[4]))
        recultTreat(data)
    sys.exit(0)
    # print rec
if __name__ == '__main__':
    main()